<template>
  <div class="project-list">
    <!-- 页面头部 -->
    <div class="page-header">
      <div class="header-content">
        <div class="header-left">
          <div class="search-bar">
            <el-input
              v-model="searchQuery"
              placeholder="搜索项目..."
              :prefix-icon="Search"
              clearable
              class="search-input"
            >
              <template #append>
                <el-select 
                  v-model="statusFilter" 
                  placeholder="状态" 
                  clearable
                  class="status-select"
                >
                  <el-option label="全部" value="" />
                  <el-option label="就绪" value="idle">
                    <div class="status-option">
                      <i class="fas fa-circle status-dot idle"></i>
                      <span>就绪</span>
                    </div>
                  </el-option>
                  <el-option label="部署中" value="deploying">
                    <div class="status-option">
                      <i class="fas fa-circle status-dot deploying"></i>
                      <span>部署中</span>
                    </div>
                  </el-option>
                  <el-option label="成功" value="success">
                    <div class="status-option">
                      <i class="fas fa-circle status-dot success"></i>
                      <span>成功</span>
                    </div>
                  </el-option>
                  <el-option label="失败" value="failed">
                    <div class="status-option">
                      <i class="fas fa-circle status-dot failed"></i>
                      <span>失败</span>
                    </div>
                  </el-option>
                </el-select>
              </template>
            </el-input>
          </div>
        </div>
        <router-link to="/project/create" class="create-btn">
          <i class="fas fa-plus"></i>
          创建新项目
        </router-link>
      </div>
    </div>

    <!-- 项目网格 -->
    <div class="project-grid" v-loading="loading">
      <div v-for="project in filteredProjects" :key="project._id" 
           class="project-card" :class="{ 'is-deploying': project.status === 'deploying' }">
        <div class="card-header">
          <div class="project-title">
            <div class="project-icon">
              <span>{{ project.name.charAt(0).toUpperCase() }}</span>
            </div>
            <div class="project-info">
              <h3>{{ project.name }}</h3>
              <p class="description">{{ project.description || '暂无描述' }}</p>
            </div>
          </div>
          <el-tag :type="getStatusType(project.status)" effect="light" size="small">
            {{ getStatusText(project.status) }}
          </el-tag>
        </div>
        
        <div class="project-meta">
          <div class="meta-item">
            <i class="fas fa-code-branch"></i>
            <span>{{ project.deploymentConfig?.branch || 'master' }}</span>
          </div>
          <div class="meta-item">
            <i class="fas fa-clock"></i>
            <span>{{ formatDate(project.lastDeployTime) }}</span>
          </div>
          <div class="meta-item">
            <i class="fas fa-server"></i>
            <span>{{ project.deploymentConfig?.serverConfig?.host || '未配置' }}</span>
          </div>
        </div>

        <div class="project-stats">
          <div class="stat-item">
            <div class="stat-value">{{ project.deployStats?.totalCount || 0 }}</div>
            <div class="stat-label">部署次数</div>
          </div>
          <div class="stat-item">
            <div class="stat-value">{{ calculateSuccessRate(project) }}%</div>
            <div class="stat-label">成功率</div>
          </div>
        </div>

        <div class="card-actions">
          <router-link :to="`/project/${project._id}`" class="action-btn view">
            查看详情
          </router-link>
          <el-button 
            type="primary" 
            class="action-btn deploy"
            :loading="project.status === 'deploying'"
            :disabled="project.status === 'deploying'"
            @click="handleDeploy(project)"
          >
            <i class="fas fa-rocket"></i>
            {{ project.status === 'deploying' ? '部署中' : '立即部署' }}
          </el-button>
          <el-dropdown trigger="click" @command="command => handleCommand(command, project)">
            <el-button circle>
              <i class="fas fa-ellipsis-v"></i>
            </el-button>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item command="configure">
                  <i class="fas fa-cog"></i>
                  配置
                </el-dropdown-item>
                <el-dropdown-item command="logs">
                  <i class="fas fa-history"></i>
                  部署日志
                </el-dropdown-item>
                <el-dropdown-item command="delete" divided>
                  <i class="fas fa-trash"></i>
                  删除项目
                </el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </div>
      </div>
    </div>

    <!-- 空状态 -->
    <div v-if="!loading && !projects.length" class="empty-state">
      <div class="empty-icon">
        <img src="@/assets/empty.svg" alt="暂无项目" />
      </div>
      <h3>暂无项目</h3>
      <p>创建一个新项目开始使用部署平台</p>
      <router-link to="/project/create" class="create-btn">
        创建新项目
      </router-link>
    </div>

    <!-- 删除确认对话框 -->
    <el-dialog
      v-model="deleteDialogVisible"
      title="删除项目"
      width="400px"
      destroy-on-close
    >
      <div class="delete-dialog-content">
        <i class="fas fa-exclamation-triangle warning-icon"></i>
        <p>确定要删除项目 "{{ selectedProject?.name }}" 吗？</p>
        <p class="warning-text">此操作不可恢复，项目的所有相关数据都将被删除。</p>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="deleteDialogVisible = false">取消</el-button>
          <el-button type="danger" @click="confirmDelete" :loading="deleting">
            确定删除
          </el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 部署日志对话框 -->
    <el-dialog
      v-model="logsDialogVisible"
      title="部署日志"
      width="800px"
    >
      <div class="deploy-logs">
        <div v-for="log in deployLogs" :key="log._id" class="log-entry">
          <div class="log-header">
            <div class="log-meta">
              <span :class="['status-dot', log.status]"></span>
              <span class="timestamp">{{ formatDate(log.startTime) }}</span>
              <span class="branch">
                <i class="fas fa-code-branch"></i>
                {{ log.branch }}
              </span>
              <span class="commit" v-if="log.commitId">
                <i class="fas fa-code-commit"></i>
                {{ log.commitId?.slice(0, 7) }}
              </span>
            </div>
            <el-tag :type="getStatusType(log.status)" size="small">
              {{ getStatusText(log.status) }}
            </el-tag>
          </div>
          <div class="log-messages">
            <div v-for="(msg, idx) in log.logs" :key="idx" 
                 :class="['message', msg.level]">
              <span class="time">{{ formatTime(msg.timestamp) }}</span>
              <span class="text">{{ msg.message }}</span>
            </div>
          </div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search } from '@element-plus/icons-vue'
import { projectApi } from '../../api/project'
import { useAuthStore } from '../../store/auth'
import { wsClient } from '../../services/websocket.service'

const router = useRouter()
const projects = ref([])
const loading = ref(false)
const searchQuery = ref('')
const statusFilter = ref('')
const deleteDialogVisible = ref(false)
const logsDialogVisible = ref(false)
const selectedProject = ref(null)
const deleting = ref(false)
const deployLogs = ref([])
const authStore = useAuthStore()

// 过滤项目列表
const filteredProjects = computed(() => {
  return projects.value.filter(project => {
    const matchesSearch = project.name.toLowerCase().includes(searchQuery.value.toLowerCase()) ||
                         project.description?.toLowerCase().includes(searchQuery.value.toLowerCase())
    const matchesStatus = !statusFilter.value || project.status === statusFilter.value
    return matchesSearch && matchesStatus
  })
})

// 获取状态类型
const getStatusType = (status) => {
  const typeMap = {
    idle: 'info',
    deploying: 'warning',
    success: 'success',
    failed: 'danger'
  }
  return typeMap[status] || 'info'
}

// 获取状态文本
const getStatusText = (status) => {
  const textMap = {
    idle: '就绪',
    deploying: '部署中',
    success: '部署成功',
    failed: '部署失败'
  }
  return textMap[status] || status
}

// 计算部署成功率
const calculateSuccessRate = (project) => {
  const { totalCount, successCount } = project.deployStats || { totalCount: 0, successCount: 0 };
  if (!totalCount) return 0;
  return Math.round((successCount / totalCount) * 100);
}

// 格式化日期
const formatDate = (date) => {
  if (!date) return '暂未部署'
  return new Date(date).toLocaleString()
}

// 格式化时间
const formatTime = (date) => {
  return new Date(date).toLocaleTimeString()
}

// 处理下拉菜单命令
const handleCommand = async (command, project) => {
  selectedProject.value = project
  switch (command) {
    case 'configure':
      router.push(`/project/${project._id}/settings`)
      break
    case 'logs':
      await showDeployLogs(project)
      break
    case 'delete':
      deleteDialogVisible.value = true
      break
  }
}

// 处理部署
const handleDeploy = async (project) => {
  try {
    await projectApi.deployProject(project._id)
    project.status = 'deploying'
    ElMessage.success('部署已开始')
  } catch (error) {
    ElMessage.error('部署失败: ' + error.message)
  }
}

// 显示部署日志
const showDeployLogs = async (project) => {
  try {
    deployLogs.value = await projectApi.getProjectLogs(project._id)
    logsDialogVisible.value = true
  } catch (error) {
    ElMessage.error('获取部署日志失败: ' + error.message)
  }
}

// 确认删除
const confirmDelete = async () => {
  if (!selectedProject.value) return
  
  deleting.value = true
  try {
    await projectApi.deleteProject(selectedProject.value._id)
    projects.value = projects.value.filter(p => p._id !== selectedProject.value._id)
    deleteDialogVisible.value = false
    ElMessage.success('项目已删除')
  } catch (error) {
    ElMessage.error('删除失败: ' + error.message)
  } finally {
    deleting.value = false
  }
}

// 获取项目列表
const fetchProjects = async () => {
  try {
    loading.value = true
    const data = await projectApi.getProjects()
    projects.value = data
  } catch (error) {
    ElMessage.error('获取项目列表失败: ' + error.message)
  } finally {
    loading.value = false
  }
}

// WebSocket处理
const setupWebSocket = () => {
  const token = authStore.token;
  if (!token) {
    console.error('Token不存在，无法建立WebSocket连接');
    return;
  }

  projects.value.forEach(project => {
    wsClient.connect(project._id, token);
    
    wsClient.on('deployStatus', (status) => {
      const targetProject = projects.value.find(p => p._id === project._id);
      if (targetProject && targetProject.status === 'deploying') {
        targetProject.status = status;
      }
    });
  });
};

onMounted(() => {
  fetchProjects().then(() => {
    setupWebSocket();
  });
});

onUnmounted(() => {
  wsClient.disconnect();
});
</script>

<style scoped>
.project-list {
  min-height: 100vh;
  background: var(--background-primary);
}

.page-header {
  position: sticky;
  top: 0;
  background: var(--glass-background);
  backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--glass-border);
  padding: var(--spacing-lg) 0;
  margin-bottom: var(--spacing-2xl);
  z-index: 10;
}

.header-content {
  max-width: 1440px;
  margin: 0 auto;
  padding: 0 var(--spacing-xl);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-left {
  display: flex;
  align-items: center;
  gap: var(--spacing-xl);
}

.search-bar {
  width: 400px;
}

.search-bar :deep(.el-input-group__append) {
  padding: 0;
  background-color: var(--background-secondary);
  border-left: 1px solid var(--border-color);
}

.search-bar :deep(.status-select) {
  width: 120px;
  margin: 0;
}

.search-bar :deep(.el-select .el-input) {
  border: none;
}

.search-bar :deep(.el-select .el-input__wrapper) {
  background: transparent;
  box-shadow: none !important;
}

.status-option {
  display: flex;
  align-items: center;
  gap: 8px;
}

.status-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
}

.status-dot.idle { background: var(--info-color); }
.status-dot.deploying { background: var(--warning-color); }
.status-dot.success { background: var(--success-color); }
.status-dot.failed { background: var(--error-color); }

.search-bar :deep(.el-input__wrapper) {
  height: 32px;
  line-height: 32px;
}

.search-bar :deep(.el-select .el-input__wrapper) {
  height: 32px;
  line-height: 32px;
  padding: 0 8px;
}

.search-bar :deep(.el-input-group__append .el-select) {
  margin: 0;
}

.search-bar :deep(.el-input-group__append) {
  border-top-right-radius: var(--radius-md);
  border-bottom-right-radius: var(--radius-md);
  overflow: hidden;
}

.create-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-sm);
  padding: var(--spacing-sm) var(--spacing-lg);
  background: var(--primary-color);
  color: white;
  border-radius: var(--radius-lg);
  text-decoration: none;
  font-weight: 500;
  transition: all var(--transition-fast);
}

.create-btn:hover {
  background: var(--primary-dark);
  transform: translateY(-1px);
}

.project-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
  gap: var(--spacing-lg);
  max-width: 1440px;
  margin: 0 auto;
  padding: 0 var(--spacing-xl);
}

.project-card {
  background: var(--background-secondary);
  border-radius: var(--radius-lg);
  padding: var(--spacing-lg);
  box-shadow: var(--shadow-sm);
  transition: all var(--transition-normal);
  border: 1px solid var(--border-color);
}

.project-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.project-card.is-deploying {
  animation: pulse 2s infinite;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: var(--spacing-lg);
}

.project-title {
  display: flex;
  gap: var(--spacing-md);
}

.project-icon {
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--primary-light);
  color: var(--primary-color);
  border-radius: var(--radius-lg);
  font-weight: var(--font-weight-medium);
  font-size: var(--font-size-xl);
}

.project-info h3 {
  margin: 0;
  margin-bottom: var(--spacing-xs);
}

.description {
  color: var(--text-secondary);
  font-size: var(--font-size-sm);
  margin: 0;
}

.project-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-md);
  margin-bottom: var(--spacing-lg);
  padding: var(--spacing-md);
  background: var(--background-tertiary);
  border-radius: var(--radius-lg);
}

.meta-item {
  display: flex;
  align-items: center;
  gap: var(--spacing-xs);
  color: var(--text-tertiary);
  font-size: var(--font-size-sm);
}

.project-stats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--spacing-md);
  margin-bottom: var(--spacing-lg);
}

.stat-item {
  text-align: center;
  padding: var(--spacing-md);
  background: var(--background-tertiary);
  border-radius: var(--radius-lg);
}

.stat-value {
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-semibold);
  color: var(--text-primary);
  margin-bottom: var(--spacing-xs);
}

.stat-label {
  font-size: var(--font-size-sm);
  color: var(--text-tertiary);
}

.card-actions {
  display: flex;
  gap: var(--spacing-sm);
}

.action-btn {
  flex: 1;
}

.action-btn.view {
  color: var(--primary-color);
  background: var(--primary-light);
  display: flex;
  align-items: center;
  justify-content: center;
}

.empty-state {
  text-align: center;
  padding: var(--spacing-3xl) var(--spacing-xl);
  color: var(--text-tertiary);
}

.empty-icon {
  margin-bottom: var(--spacing-xl);
  color: var(--text-quaternary);
}

.empty-icon img {
  width: 200px;
  height: 200px;
  opacity: 0.5;
}

.empty-state h3 {
  font-size: var(--font-size-xl);
  margin-bottom: var(--spacing-sm);
  color: var(--text-primary);
}

.empty-state p {
  margin-bottom: var(--spacing-xl);
}

.warning-icon {
  font-size: 48px;
  color: var(--warning-color);
  margin-bottom: var(--spacing-lg);
}

.warning-text {
  color: var(--text-tertiary);
  font-size: var(--font-size-sm);
  margin-top: var(--spacing-sm);
}

.deploy-logs {
  max-height: 600px;
  overflow-y: auto;
}

.log-entry {
  background: var(--background-tertiary);
  border-radius: var(--radius-lg);
  padding: var(--spacing-lg);
  margin-bottom: var(--spacing-md);
}

.log-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--spacing-md);
}

.log-meta {
  display: flex;
  align-items: center;
  gap: var(--spacing-md);
  color: var(--text-tertiary);
  font-size: var(--font-size-sm);
}

.log-messages {
  font-family: var(--font-family-mono);
  font-size: var(--font-size-sm);
}

.message {
  padding: var(--spacing-xs) 0;
}

.message .time {
  color: var(--text-tertiary);
  margin-right: var(--spacing-md);
}

.message.info { color: var(--info-color); }
.message.warning { color: var(--warning-color); }
.message.error { color: var(--error-color); }

@keyframes pulse {
  0% { box-shadow: 0 0 0 0 rgba(var(--primary-color-rgb), 0.4); }
  70% { box-shadow: 0 0 0 10px rgba(var(--primary-color-rgb), 0); }
  100% { box-shadow: 0 0 0 0 rgba(var(--primary-color-rgb), 0); }
}

@media (max-width: 768px) {
  .project-grid {
    grid-template-columns: 1fr;
  }

  .search-bar {
    width: 100%;
  }

  .header-content {
    flex-direction: column;
    gap: var(--spacing-md);
  }
}
</style> 